#include "GlowDevice.h"
#include <iostream>

namespace glow
{
    using namespace std;
    
    GlowDevice *GlowDevice::_inst = NULL;

  GlowDevice::GlowDevice() : _size(Vector2i(800, 600)), _fullScreen(false), _n(0), _fps(0), _current_time(0), _start_time(0)
	{
		if (glfwInit() == GL_FALSE)
			cerr << "Can't load GLFW Library" << endl;
	}
	
	GlowDevice::~GlowDevice()
	{
		EventManager::destroy();
		Renderer::destroy();
		ResourceManager::destroy();
		glfwTerminate();
	}
	
	void GLFWCALL eventWindowResize(int width, int height)
	{
		GlowDevice::getInstance()->setWindowSize(width, height);
	}
	
	bool GlowDevice::init(int width, int height, bool fullscreen)
	{
		_size.x = width;
		_size.y = height;
		fullscreen = fullscreen;
		int state = GL_TRUE;
		
		if(fullscreen)
			state = glfwOpenWindow (_size.x, _size.y, 5, 6, 5, 0, 8, 0, GLFW_FULLSCREEN);
		else
			state = glfwOpenWindow (_size.x, _size.y, 5, 6, 5, 0, 8, 0, GLFW_WINDOW);
			
		if(state == GL_FALSE)
		{
			cerr << "Can't open window" << endl;
			glfwTerminate();
			return false;
		}
		
		glfwSetWindowSizeCallback(eventWindowResize);
		
		//Renderer::getInstance()->init();
		//Renderer::getInstance()->initExtensions();
		EventManager::getInstance()->init();
		
		return true;
	}
	
	void GlowDevice::setWindowTitle(string title)
	{
		glfwSetWindowTitle(title.c_str());
	}
	
	void GlowDevice::setWindowSize(int width, int height)
	{
		_size.x = width;
		_size.y = height;
		glfwSetWindowSize(_size.x, _size.y);
		Renderer::getInstance()->resize(_size.x, _size.y);
	}
	
	void GlowDevice::setWindowPos(int x, int y)
	{
		glfwSetWindowPos(x, y);
	}
	
	const Vector2i &GlowDevice::getSize() const
	{
		return _size;
	}
	
	Renderer *GlowDevice::getRenderer() const
	{
		return Renderer::getInstance();
	}

	EventManager *GlowDevice::getEventManager() const
	{
		return EventManager::getInstance();
	}

	ResourceManager *GlowDevice::getResourceManager() const
	{
		return ResourceManager::getInstance();
	}
	
	GlowDevice *GlowDevice::getInstance()
	{
		if(!_inst)
			_inst = new GlowDevice();
		return _inst;
	}
	
	void GlowDevice::destroy()
	{
		if(_inst)
			delete _inst;
		_inst = NULL;
	}
	
	void GlowDevice::showCursor(bool show)
	{
		if(show) glfwEnable(GLFW_MOUSE_CURSOR);
		else glfwDisable(GLFW_MOUSE_CURSOR);
	}

	double GlowDevice::getFPS()
	{	
	  _n++;
	  _current_time = glfwGetTime();
	    
	  if ((_current_time - _start_time) >= 1.0)
	    {
	      _fps = _n;// / (_current_time - _start_time);
	      _n = 0;
	      _start_time = _current_time;
		
	      return _fps;
	    }
	  return _fps;
	}

}
